package com.alt.utils;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.text.NumberFormat;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.BitmapFactory.Options;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;

import com.alt.R;
import com.alt.connector.RestClient;
import com.alt.manager.ALTAppMgr;

public class ALTSysUtils {

	// kill current app
	public static void processKill(final Context context) {
		// #1. first check api level.
		int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
		if (sdkVersion < 8) {
			// #2. if we can use restartPackage method, just use it.
			ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
			am.restartPackage(context.getPackageName());
		} else {
			// #3. else, we should use killBackgroundProcesses method.
			new Thread(new Runnable() {
				public void run() {
					ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
					String name = context.getApplicationInfo().processName;
					// pooling the current application process importance
					// information.
					while (true) {
						List<RunningAppProcessInfo> list = am.getRunningAppProcesses();
						if (list == null) {
							break;
						}

						for (RunningAppProcessInfo i : list) {
							if (i.processName.equals(name) == true) {
								// #4. kill the process,
								// only if current application importance is
								// less than IMPORTANCE_BACKGROUND
								if (i.importance >= RunningAppProcessInfo.IMPORTANCE_BACKGROUND)
									am.restartPackage(context.getPackageName()); // simple
								// wrapper
								// of
								// killBackgrounProcess
								else
									Thread.yield();
								break;
							}
						}
					}
				}
			}, "Process Killer").start();
		}
	}

	/**
	 * check internet connection
	 * 
	 * @param activity
	 * @return
	 */
	public static boolean checkInternetAvailable(Activity activity) {
		ConnectivityManager cm = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo ni = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		boolean isWifiConn = ni.isConnected();
		ni = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
		boolean isMobileConn = ni.isConnected();

		if (isWifiConn || isMobileConn) {
			String svcUrl = RestClient.applicationUrl();

			if (connectToUrl(svcUrl)) {
				return true;
			}

			return false;
		}

		return false;

	}

	/**
	 * 
	 * @param url
	 * @return
	 */
	public static boolean connectToUrl(String siteUrl) {
		HttpURLConnection connection;
		try {
			Log.i("PGASysUtils", "connectToUrl: " + siteUrl);

			URL url = new URL(siteUrl);

			connection = (HttpURLConnection) url.openConnection();
			connection.setRequestProperty("User-Agent", "yourAgent");
			connection.setRequestProperty("Connection", "close");
			connection.setConnectTimeout(1000);
			connection.connect();

			int respCode = connection.getResponseCode();

			// if (respCode == 200 || respCode == 404) {
			return true;
			// }
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public static String formatTelNumber(String TelNum) {
		// return PhoneNumberUtils.formatNumber(TelNum);
		int nLen = TelNum.length();
		if (nLen == 10) {
			String Tel1 = TelNum.substring(0, 3);
			String Tel2 = TelNum.substring(3, 6);
			String Tel3 = TelNum.substring(6, 10);
			return String.format("%s-%s-%s", Tel1, Tel2, Tel3);
		}

		if (nLen == 11) {
			String Tel1 = TelNum.substring(0, 3);
			String Tel2 = TelNum.substring(3, 7);
			String Tel3 = TelNum.substring(7, 11);
			return String.format("%s-%s-%s", Tel1, Tel2, Tel3);
		}
		return TelNum;
	}

	public static String formatMoney(int nMoney) {
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(3);
		return nf.format(nMoney);
	}

	public static String formatMoney(float nMoney) {
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(3);
		return nf.format(nMoney);
	}

	public static String formatMoney(double nMoney) {
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(3);
		return nf.format(nMoney);
	}

	public static void enableActivityAlias(Context context, String aliasNameSpace, boolean enable) {
		Log.i("PGASysUtils", "enableActivityAlias:" + aliasNameSpace + "-" + enable);

		PackageManager pkgMgr = context.getPackageManager();
		ComponentName comp = new ComponentName("com.pga", aliasNameSpace);

		pkgMgr.setComponentEnabledSetting(comp, enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
	}

	public static String format(String formatText) {
		return formatText;
	}

	public static String format(String formatText, Object param0) {
		return format(formatText, new Object[] { param0 });
	}

	public static String format(String formatText, Object param0, Object param1) {
		return format(formatText, new Object[] { param0, param1 });
	}

	public static String format(String formatText, Object param0, Object param1, Object param2) {
		return format(formatText, new Object[] { param0, param1, param2 });
	}

	public static String format(String formatText, Object param0, Object param1, Object param2, Object param3) {
		return format(formatText, new Object[] { param0, param1, param2, param3 });
	}

	public static String format(String formatText, Object param0, Object param1, Object param2, Object param3, Object param4) {
		return format(formatText, new Object[] { param0, param1, param2, param3, param4 });
	}

	public static String format(String formatText, Object param0, Object param1, Object param2, Object param3, Object param4, Object param5) {
		return format(formatText, new Object[] { param0, param1, param2, param3, param4, param5 });
	}

	public static String format(String formatText, Object[] params) {
		Object[] newParams = new Object[params.length];
		for (int i = 0; i < newParams.length; i++) {
			if (params[i] == null) {
				continue;
			}

			if (params[i].getClass().getSimpleName().equals("String")) {
				try {
					String newString = URLEncoder.encode((String) params[i], "utf-8");
					newParams[i] = newString;
				} catch (Exception e) {
					// TODO: handle exception
				}

			} else {
				newParams[i] = params[i];
			}
		}

		return String.format(formatText, newParams);
	}

	public static AlertDialog createProgressDialog(Activity context) {
		AlertDialog.Builder builder = new AlertDialog.Builder(context.getParent() != null ? context.getParent() : context);
		View progressView = LayoutInflater.from(context.getParent() != null ? context.getParent() : context).inflate(R.layout.screen_progress_dialog, null);
		// progressView.setBackgroundDrawable(new
		// ColorDrawable(android.graphics.Color.TRANSPARENT));
		builder.setView(progressView);

		AlertDialog progressDialog = builder.create();
		progressDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

		return progressDialog;
	}

	public static void copyStream(InputStream is, OutputStream os) {
		final int buffer_size = 1024;
		try {
			byte[] bytes = new byte[buffer_size];
			for (;;) {
				int count = is.read(bytes, 0, buffer_size);
				if (count == -1)
					break;
				os.write(bytes, 0, count);
			}
		} catch (Exception ex) {
		}
	}

	/**
	 * 
	 * @param bmp
	 * @return
	 */
	public static byte[] getBitmapBytes(Bitmap bmp) {
		if (bmp == null) {
			return null;
		}

		int size = bmp.getRowBytes() * bmp.getHeight();
		ByteBuffer b = ByteBuffer.allocate(size);
		bmp.copyPixelsToBuffer(b);
		byte[] bytes = new byte[size];
		try {
			b.get(bytes, 0, bytes.length);
		} catch (BufferUnderflowException e) {
			// always happens
		}

		return bytes;
	}

	/**
	 * 
	 * @param bData
	 * @return
	 */
	public static Bitmap getBitmapFromBytes(byte[] bData) {
		Log.d("PGASysUtils", "getBitmapFromBytes");

		// InputStream is = new ByteArrayInputStream(bData);
		InputStream is = new ByteArrayInputStream(bData);
		BufferedInputStream buf = new BufferedInputStream(is, 8192);

		Options opts = new Options();
		opts.inJustDecodeBounds = true;
		Bitmap bm = BitmapFactory.decodeStream(buf, null, opts);
		return bm;
	}

	public static Bitmap getBitmapFromBytes(byte[] bData, int width, int height) {
		Log.d("PGASysUtils", "getBitmapFromBytes");
		InputStream is = new ByteArrayInputStream(bData);
		return BitmapFactory.decodeStream(is);
	}

	public static String getBitmapUrl(String fileId) {
		String service_url = "system/file/url/%s";
		String url = ALTSysUtils.format(service_url, fileId);
		url = RestClient.systemApiUrl(url);
		return url;
	}

	public static String formatCardNo(String cardNo) {
		if (cardNo.length() != 16) {
			return cardNo;
		}

		StringBuilder sb = new StringBuilder();
		sb.append(cardNo.substring(0, 4));
		sb.append("-");
		sb.append(cardNo.substring(4, 8));
		sb.append("-");
		sb.append(cardNo.substring(8, 12));
		sb.append("-");
		sb.append(cardNo.substring(12));
		return sb.toString();
	}

	/**
	 * 
	 * @param imageURL
	 * @return
	 */
	public static Bitmap getBitmapFromUrl(String fileId) {
		String service_url = "common/getfilestream/%s";

		String imageURL = ALTSysUtils.format(service_url, fileId);
		imageURL = RestClient.apiUrl(imageURL);

		URL myImageURL = null;

		try {
			myImageURL = new URL(imageURL);
		} catch (MalformedURLException error) {
			error.printStackTrace();
		}

		Bitmap myBitmap = null;
		// InputStream in = null;
		// BufferedOutputStream out = null;

		try {

			HttpURLConnection connection = (HttpURLConnection) myImageURL.openConnection();
			connection.setDoInput(true);
			connection.connect();

			InputStream input = myImageURL.openStream();
			myBitmap = BitmapFactory.decodeStream(input);

			/*
			 * DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet
			 * request = new HttpGet(imageURL); HttpResponse response =
			 * httpClient.execute(request);
			 * 
			 * InputStream input = response.getEntity().getContent(); myBitmap =
			 * BitmapFactory.decodeStream(input);
			 */

		} catch (IOException e) {
			e.printStackTrace();
		}

		return myBitmap;
	}

	public static String parseRestString(String value) {
		return value.replace("\"", "");
	}

	/**
	 * 
	 * @param context
	 * @param urlString
	 * @return
	 */
	public static Bitmap getBitmap(Context context, String fileId) {
		String urlString = getBitmapUrl(fileId);
		String filename = fileId;

		ALTAppMgr.getInstance().Log("PGASysUtils", "getBitmap:" + urlString);
		ALTAppMgr.getInstance().Log("PGASysUtils", "getBitmap:" + filename);

		File cacheDir = null;

		try {
			// Find the dir to save cached images
			if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
				cacheDir = new File(android.os.Environment.getExternalStorageDirectory(), "Android/data/LazyList");
			} else {
				cacheDir = context.getCacheDir();
			}
		} catch (Exception e) {
			// TODO: handle exception
		}

		if (cacheDir == null) {
			return null;
		}

		if (!cacheDir.exists())
			cacheDir.mkdirs();

		File f = new File(cacheDir, filename);
		try {
			if (!f.exists()) {
				Bitmap bitmap = null;
				InputStream is = new URL(urlString).openStream();
				OutputStream os = new FileOutputStream(f);
				copyStream(is, os);
				os.close();
				bitmap = decodeFile(f);

				if (bitmap != null) {
					Log.i("getBitmap", bitmap == null ? "NULL" : "NOTNULL");
				}

				return bitmap;
			} else {
				Bitmap bitmap = decodeFile(f);
				return bitmap;
			}

		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}
	}

	// decodes image and scales it to reduce memory consumption
	private static Bitmap decodeFile(File f) {
		try {
			// decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;
			BitmapFactory.decodeStream(new FileInputStream(f), null, o);

			// Find the correct scale value. It should be the power of 2.
			final int REQUIRED_SIZE = 70;
			int width_tmp = o.outWidth, height_tmp = o.outHeight;
			int scale = 1;
			while (true) {
				if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
					break;
				width_tmp /= 2;
				height_tmp /= 2;
				scale *= 2;
			}

			// decode with inSampleSize
			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = scale;

			return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);

		} catch (FileNotFoundException e) {
		}
		return null;
	}

	// get Rounded bitmap [native bitmap]
	public static Bitmap getRoundedBitmap(Bitmap bm, int scale) {
		return getRoundedRectBitmap(bm, scale);
	}

	// set rounded bitmap
	public static Bitmap getRoundedRectBitmap(Bitmap bitmap, int pixels) {
		// declare variable
		int color;
		Paint paint;
		Rect rect;
		RectF rectF;
		Bitmap result;
		Canvas canvas;
		float roundPx;

		result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
		canvas = new Canvas(result);

		color = 0xff424242;
		paint = new Paint();
		rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		rectF = new RectF(rect);
		roundPx = pixels;

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return result;
	}

	// end set rounded bitmap

	// check email
	public static boolean isValidateEmail(String email) {
		Pattern pattern;
		Matcher matcher;
		String EMAIL_PATTERN = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
		pattern = Pattern.compile(EMAIL_PATTERN);
		matcher = pattern.matcher(email);
		return matcher.matches();
	}

	@SuppressWarnings("unused")
	public static Bitmap byte2bitmap(byte[] data) {
		InputStream inputStream = new ByteArrayInputStream(data);
		Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
		return ALTSysUtils.getRoundedBitmap(bitmap, 10);
	}

	public static String encodeImage(byte[] data) {
		return Base64.encodeToString(data, Base64.DEFAULT);
	}

	public static void recycle(ImageView iv) {
		if (iv != null) {
			Drawable drawable = iv.getDrawable();
			if (drawable instanceof BitmapDrawable) {

				Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
				if (null != bitmap && !bitmap.isRecycled()) {
					bitmap.recycle();
					bitmap = null;
					iv.setImageBitmap(null);
					iv.setImageDrawable(null);
				}

			}
		}
	}

}
